/*================================================================
*   Copyright (C) 2024 baichao All rights reserved.
*
*   文件名称：PIPE_BUF.c
*   创 建 者：baichao
*   创建日期：2024年05月12日
*   描    述：多次执行该程序，总会遇到某次8KB或12KB的写入，中间混杂了其他字符。
*            比如下面的一次执行结果中，n=16和n=17就出现了一个消息被截断的情况：B如果不被截断应该是连续两条，C是连续三条。
*
================================================================*/

/*
 * apid=13317 write 4096 bytes to pipe
 * apid=13317 write 4096 bytes to pipe
 * apid=13317 write 4096 bytes to pipe
 * apid=13317 write 4096 bytes to pipe
 * apid=13317 write 4096 bytes to pipe
 * apid=13317 write 4096 bytes to pipe
 * apid=13317 write 4096 bytes to pipe
 * apid=13317 write 4096 bytes to pipe
 * apid=13317 write 4096 bytes to pipe
 * cpid=13319 write 12288 bytes to pipe
 * apid=13317 write 4096 bytes to pipe
 * bpid=13318 write 8192 bytes to pipe
 * n=01 pid=13316 read 4096 bytes from pipe buf[4095]=A
 * n=02 pid=13316 read 4096 bytes from pipe buf[4095]=B
 * n=03 pid=13316 read 4096 bytes from pipe buf[4095]=B
 * n=04 pid=13316 read 4096 bytes from pipe buf[4095]=A
 * cpid=13319 write 12288 bytes to pipe
 * n=05 pid=13316 read 4096 bytes from pipe buf[4095]=C
 * n=06 pid=13316 read 4096 bytes from pipe buf[4095]=C
 * n=07 pid=13316 read 4096 bytes from pipe buf[4095]=C
 * cpid=13319 write 12288 bytes to pipe
 * n=08 pid=13316 read 4096 bytes from pipe buf[4095]=A
 * n=09 pid=13316 read 4096 bytes from pipe buf[4095]=A
 * cpid=13319 write 12288 bytes to pipe
 * n=10 pid=13316 read 4096 bytes from pipe buf[4095]=A
 * n=11 pid=13316 read 4096 bytes from pipe buf[4095]=A
 * n=12 pid=13316 read 4096 bytes from pipe buf[4095]=A
 * cpid=13319 write 12288 bytes to pipe
 * n=13 pid=13316 read 4096 bytes from pipe buf[4095]=A
 * n=14 pid=13316 read 4096 bytes from pipe buf[4095]=A
 * n=15 pid=13316 read 4096 bytes from pipe buf[4095]=A
 * n=16 pid=13316 read 4096 bytes from pipe buf[4095]=C
 * cpid=13319 write 12288 bytes to pipe
 * n=17 pid=13316 read 4096 bytes from pipe buf[4095]=B
 * n=18 pid=13316 read 4096 bytes from pipe buf[4095]=C
 * n=19 pid=13316 read 4096 bytes from pipe buf[4095]=C
 * n=20 pid=13316 read 4096 bytes from pipe buf[4095]=C
 * cpid=13319 write 12288 bytes to pipe
 * n=21 pid=13316 read 4096 bytes from pipe buf[4095]=C
 * cpid=13319 write 12288 bytes to pipe
 * n=22 pid=13316 read 4096 bytes from pipe buf[4095]=C
 * n=23 pid=13316 read 4096 bytes from pipe buf[4095]=C
 * n=24 pid=13316 read 4096 bytes from pipe buf[4095]=C
 * n=25 pid=13316 read 4096 bytes from pipe buf[4095]=C
 * bpid=13318 write 8192 bytes to pipe
 * cpid=13319 write 12288 bytes to pipe
 * n=26 pid=13316 read 4096 bytes from pipe buf[4095]=C
 * n=27 pid=13316 read 4096 bytes from pipe buf[4095]=C
 * n=28 pid=13316 read 4096 bytes from pipe buf[4095]=C
 * n=29 pid=13316 read 4096 bytes from pipe buf[4095]=C
 * n=30 pid=13316 read 4096 bytes from pipe buf[4095]=C
 * cpid=13319 write 12288 bytes to pipe
 * n=31 pid=13316 read 4096 bytes from pipe buf[4095]=C
 * bpid=13318 write 8192 bytes to pipe
 * n=32 pid=13316 read 4096 bytes from pipe buf[4095]=C
 * bpid=13318 write 8192 bytes to pipe
 * n=33 pid=13316 read 4096 bytes from pipe buf[4095]=C
 * n=34 pid=13316 read 4096 bytes from pipe buf[4095]=C
 * bpid=13318 write 8192 bytes to pipe
 * n=35 pid=13316 read 4096 bytes from pipe buf[4095]=C
 * n=36 pid=13316 read 4096 bytes from pipe buf[4095]=C
 * n=37 pid=13316 read 4096 bytes from pipe buf[4095]=C
 * n=38 pid=13316 read 4096 bytes from pipe buf[4095]=C
 * n=39 pid=13316 read 4096 bytes from pipe buf[4095]=C
 * bpid=13318 write 8192 bytes to pipe
 * bpid=13318 write 8192 bytes to pipe
 * n=40 pid=13316 read 4096 bytes from pipe buf[4095]=B
 * bpid=13318 write 8192 bytes to pipe
 * n=41 pid=13316 read 4096 bytes from pipe buf[4095]=C
 * n=42 pid=13316 read 4096 bytes from pipe buf[4095]=C
 * bpid=13318 write 8192 bytes to pipe
 * n=43 pid=13316 read 4096 bytes from pipe buf[4095]=B
 * n=44 pid=13316 read 4096 bytes from pipe buf[4095]=C
 * n=45 pid=13316 read 4096 bytes from pipe buf[4095]=C
 * n=46 pid=13316 read 4096 bytes from pipe buf[4095]=B
 * n=47 pid=13316 read 4096 bytes from pipe buf[4095]=B
 * bpid=13318 write 8192 bytes to pipe
 * n=48 pid=13316 read 4096 bytes from pipe buf[4095]=B
 * n=49 pid=13316 read 4096 bytes from pipe buf[4095]=B
 * n=50 pid=13316 read 4096 bytes from pipe buf[4095]=B
 * n=51 pid=13316 read 4096 bytes from pipe buf[4095]=B
 * n=52 pid=13316 read 4096 bytes from pipe buf[4095]=B
 * n=53 pid=13316 read 4096 bytes from pipe buf[4095]=B
 * n=54 pid=13316 read 4096 bytes from pipe buf[4095]=B
 * n=55 pid=13316 read 4096 bytes from pipe buf[4095]=B
 * n=56 pid=13316 read 4096 bytes from pipe buf[4095]=B
 * n=57 pid=13316 read 4096 bytes from pipe buf[4095]=B
 * n=58 pid=13316 read 4096 bytes from pipe buf[4095]=B
 * n=59 pid=13316 read 4096 bytes from pipe buf[4095]=B
 * n=60 pid=13316 read 4096 bytes from pipe buf[4095]=B
 */

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#define BUF_4K 4 * 1024
#define BUF_8K 8 * 1024
#define BUF_12K 12 * 1024
int main(void) {
  char a[BUF_4K];
  char b[BUF_8K];
  char c[BUF_12K];
  memset(a, 'A', sizeof(a));
  memset(b, 'B', sizeof(b));
  memset(c, 'C', sizeof(c));
  int pipefd[2];
  int ret = pipe(pipefd);
  if (ret == -1) {
    fprintf(stderr, "failed to create pipe (%s)\n", strerror(errno));
    return 1;
  }
  pid_t pid;
  pid = fork();
  if (pid == 0)  // 第一个子进程
  {
    close(pipefd[0]);
    int loop = 0;
    while (loop++ < 10) {
      ret = write(pipefd[1], a, sizeof(a));
      printf("apid=%d write %d bytes to pipe\n", getpid(), ret);
    }
    exit(0);
  }
  pid = fork();
  if (pid == 0)  // 第二个子进程
  {
    close(pipefd[0]);
    int loop = 0;
    while (loop++ < 10) {
      ret = write(pipefd[1], b, sizeof(b));
      printf("bpid=%d write %d bytes to pipe\n", getpid(), ret);
    }
    exit(0);
  }
  pid = fork();
  if (pid == 0)  // 第三个子进程
  {
    close(pipefd[0]);
    int loop = 0;
    while (loop++ < 10) {
      ret = write(pipefd[1], c, sizeof(c));
      printf("cpid=%d write %d bytes to pipe\n", getpid(), ret);
    }
    exit(0);
  }
  close(pipefd[1]);
  sleep(1);
  int fd = open("test.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
  char buf[1024 * 4] = {0};
  int n = 1;
  while (1) {
    ret = read(pipefd[0], buf, sizeof(buf));
    if (ret == 0) break;
    printf("n=%02d pid=%d read %d bytes from pipe buf[4095]=%c\n", n++,
           getpid(), ret, buf[4095]);
    write(fd, buf, ret);
  }
  return 0;
}